<?php
/**
 * Created by PhpStorm
 * User: ZhuYunlong2018
 * Email: 920200256@qq.com
 * Date: 2022/1/5
 * Time: 11:27
 */

namespace app\lib;

use app\lib\exception\AuthException;
use think\facade\Request;


/**
 * 管理员登录错误锁
 * Class AuthErrorLock
 * @package app\lib
 */
class AuthErrorLock
{

    use Instance;

    protected $ip;

    protected $name;

    const IP_ERROR = 10;

    const NAME_ERROR = 5;

    protected function __construct($name = 'admin')
    {
        $this->ip = Request::host();
        $this->name = $name;
    }

    const IP_KEY = "ip_key:";

    const NAME_KEY = "name_key:";

    protected function ipKey()
    {
        return self::IP_KEY . $this->ip;
    }

    protected function nameKey() {
        return self::NAME_KEY . $this->name;
    }

    protected function incrementIpError()
    {
        Redis::instance()->incr($this->ipKey(), 1);
        Redis::instance()->expire($this->ipKey(), 300);
    }

    protected function incrementNameError()
    {
        Redis::instance()->incr($this->nameKey(), 1);
        Redis::instance()->expire($this->ipKey(), 300);
    }

    public function incrementError() {
        $this->incrementNameError();
        $this->incrementIpError();
    }

    /**
     * 校验操作
     * @throws AuthException
     */
    public function check() {
        $this->checkIp();
        $this->checkName();
    }

    /**
     * 校验登录者IP
     * @throws AuthException
     */
    protected function checkIp() {
        $error = Redis::instance()->get($this->ipKey());
        if ($error && intval($error) > self::IP_ERROR) {
            if (intval($error) !== 999) {
                Redis::instance()->set($this->ipKey(), 999);
                Redis::instance()->expire($this->ipKey(), 86400);
            }
            throw new AuthException('当前登录失败次数过多，请24小时候再进行尝试登录');
        }
    }

    /**
     * 校验登录者账户号
     * @throws AuthException
     */
    protected function checkName() {
        $error = Redis::instance()->get($this->nameKey());
        if ($error && intval($error) > self::NAME_ERROR) {
            if (intval($error) !== 999) {
                Redis::instance()->set($this->nameKey(), 999);
                Redis::instance()->expire($this->nameKey(), 3600);
            }
            throw new AuthException('当前登录失败次数过多，请1小时候再进行尝试登录');
        }
    }

}